package com.xzg.apply.service;

import com.xzg.apply.dao.ApplyMapper;
import com.xzg.apply.entity.Apply;
import com.xzg.common.constants.Constant;
import com.xzg.common.exception.XZGException;
import com.xzg.common.page.PageQueryBean;
import com.xzg.common.push.AppPush;
import com.xzg.common.vo.QueryCondition;
import com.xzg.completeMissionApply.dao.CompleteMissionApplyMapper;
import com.xzg.completeMissionApply.entity.CompleteMissionApply;
import com.xzg.middleTable.dao.UserMissionMapper;
import com.xzg.middleTable.entity.UserMission;
import com.xzg.mission.dao.MissionMapper;
import com.xzg.mission.entity.Mission;
import com.xzg.myMission.dao.MyMissionMapper;
import com.xzg.myMission.entity.MyMission;
import com.xzg.past.dao.PastRecordsMapper;
import com.xzg.user.dao.UserMapper;
import com.xzg.user.entity.User;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.apache.commons.collections.CollectionUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
public class ApplyServiceImpl implements ApplyService {

    @Autowired
    private ApplyMapper applyMapper;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private MissionMapper missionMapper;

    @Autowired
    private UserMissionMapper userMissionMapper;

    @Autowired
    private MyMissionMapper myMissionMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private PastRecordsMapper pastRecordsMapper;

    @Autowired
    private CompleteMissionApplyMapper completeMissionApplyMapper;


    @Override
    @Transactional
    public void startApply(Mission mission) throws XZGException {
        Apply apply = new Apply();
        User user = (User) SecurityUtils.getSubject().getSession().getAttribute("userinfo");
        apply.setPublisher(mission.getPublisher());
        apply.setStatus(Constant.APPLY_STATUS_ONGOING);
        apply.setStatus(Constant.APPLY_STATUS_ONGOING);
        apply.setUserId(user.getId());
        apply.setMissionName(mission.getMissionName());
        apply.setMissionId(mission.getMissionId());
        apply.setStartDate(new Date());
        apply.setApplyUsername(user.getUsername());
        //申请者不能是发布人
        if (user.getId() == mission.getPublisherId()) {
            throw new XZGException("Please do not apply for");
        }
        //查询此人是否重复申请
        int count = userMissionMapper.findDistinct(mission.getMissionId(), user.getId());
        if (count > 0) {
            //请勿重复申请
            throw new XZGException("Do not repeat the application");
        }
        //查询该任务是否超过可申请人数
        QueryCondition condition = new QueryCondition();
        condition.setTaskId(mission.getMissionId() + "");
        condition.setUserId(user.getId());
        int userCount = userMissionMapper.selectMissionCount(condition);
        if (userCount >= mission.getManNum() + 8) {
            //已满员
            throw new XZGException("Task full");
        }
        if (userCount == mission.getManNum() - 1) {
            //改变任务申请状态
            mission.setTaskStatus(Constant.MISSION_STATUS_NOT_REFUSE);
            missionMapper.updateByPrimaryKeySelective(mission);
        }
        if (userCount < mission.getManNum()) {
            //插入中间表
            UserMission userMission = new UserMission();
            userMission.setTaskId(mission.getMissionId());
            userMission.setUserId(condition.getUserId());
            userMissionMapper.insertSelective(userMission);
        }
        //插入数据库申请表
        applyMapper.insertSelective(apply);
        HashMap<String, Object> map = new HashMap<>();
        map.put(Constant.APPLY_SIGN, apply);
        map.put(Constant.NEXT_HANDLER, apply.getPublisher());
        //启动申请
        ProcessInstance instance = runtimeService.startProcessInstanceByKey(Constant.APPLY_FLOW_ID, map);
        //提交申请任务
        Task task = taskService.createTaskQuery().processInstanceId(instance.getId()).singleResult();
        taskService.complete(task.getId(), map);
        //发送推送给上级
        user = userMapper.selectByPrimaryKey(mission.getPublisherId());
        AppPush.pushSingle("{\"title\":\"猫咪老师\",\"content\":\"您有一份新的申请,请及时处理\"}", user.getCID());
        AppPush.pushSingle2("{\"title\":\"猫咪老师\",\"content\":\"您有一份新的申请,请及时处理\",\"payload\":\"您有一份新的申请,请及时处理\"}", user.getCID());
    }

    @Override
    @Transactional
    public PageQueryBean listTask(String username, QueryCondition condition) {
        PageQueryBean result = new PageQueryBean();
        List<Task> tasks = taskService.createTaskQuery().processVariableValueEquals(username).list();
        username = username + "1complete";
        List<Task> completeTask = taskService.createTaskQuery().processVariableValueEquals(username).list();
        if (CollectionUtils.isNotEmpty(tasks)) {
            //有问题
            int count = applyMapper.count(condition);
            result.setTotalRows(count);
            result.setCurrentPage(condition.getCurrentPage());
            result.setPageSize(condition.getPageSize());
            List<Apply> list = applyMapper.selectByCondition(condition);
            int i = 0;
            for (Task task : tasks) {
                Map<String, Object> variable = taskService.getVariables(task.getId());
                Apply apply = (Apply) variable.get(Constant.APPLY_SIGN);
                apply.setTaskId(task.getId());
                if (i < list.size()) {
                    list.get(i++).setTaskId(task.getId());
                }
            }
            result.setItems(list);
        }
        if (CollectionUtils.isNotEmpty(completeTask)) {
            List<CompleteMissionApply> clist = completeMissionApplyMapper.selectByCondition(condition);
            int b = 0;
            for (Task task : completeTask) {
                Map<String, Object> variable = taskService.getVariables(task.getId());
                CompleteMissionApply complete = (CompleteMissionApply) variable.get(Constant.COMPLETE_APPLY_SIGN);
                complete.setTaskId(task.getId());
//                 completeList.add(complete);
                if (b < clist.size()) {
                    clist.get(b++).setTaskId(task.getId());
                }
            }
            result.setCompleteItems(clist);
        }
        return result;
    }

    /**
     * @Author Ye
     * Date 2018-03-13 16:05
     * @Description 任务接受后修改任务的状态，并添加到申请人的任务表，还没添加申请的id,需要从前台获取，还有头像
     */
    @Override
    @Transactional
    public int approve(Apply apply, Mission mission, User user) {
        int i = 0;
        taskService.createTaskQuery().taskId(apply.getTaskId()).singleResult();
        User currentUser = (User) SecurityUtils.getSubject().getSession().getAttribute("userinfo");
        //取到该条任务可以申请的总人数
        Mission mission1 = missionMapper.selectByPrimaryKey(mission.getMissionId());
        //查询目前该任务状态为已通过的数据
        apply.setMissionId(mission.getMissionId());
        //已经申请的人数
        int count = pastRecordsMapper.selectBystatus(apply);
        //任务满员删除其他申请
        if (count == mission1.getManNum() - 1) {
            //发出列表推送
            //发给其他申请人，问题：全部的人都推送了，应该只推送申请了该任务但是没有没有被通过的人
            //怎么查：查询该申请表并且状态为待审批的用户的CID
            //没经过测试，在查询的时候可能在sql的入参上会报错
            Byte status = 1;
            List<Long> userIds = applyMapper.selectUserId(mission.getMissionId(), status);
            HashMap<String, Object> userIdParam = new HashMap<>();
            userIdParam.put("userIds", userIds);
            List<User> cidList = userMapper.selectCid(userIdParam);
            for (User cid : cidList) {
                AppPush.pushSingle("{\"title\":\"猫咪老师\",\"content\":\"喵！~领取任务失败了哦！\"}", cid.getCID());
                AppPush.pushSingle2("{\"title\":\"猫咪老师\",\"content\":\"喵！~领取任务失败了哦！\",\"payload\":\"喵！~\"}", cid.getCID());
            }
            applyMapper.deleteByMissionId(mission.getMissionId());
        }
        if (Constant.APPLY_STATUS_PSSS == apply.getStatus()) {
            mission.setTaskStatus(Constant.MISSION_STATUS_UNDERWAY);
            //修改任务的状态
            missionMapper.updateByPrimaryKeySelective(mission);
            //插入申请人的任务表
            MyMission myMission = new MyMission();
            mission = missionMapper.selectByPrimaryKey(mission.getMissionId());
            myMission.setAward(mission.getAward());
            myMission.setDeduct(mission.getDeduct());
            myMission.setMissionId(mission.getMissionId());
            myMission.setMissionContent(mission.getContent());
            myMission.setMyDate(mission.getMissionDate());
            myMission.setMissionName(mission.getMissionName());
            myMission.setTaskStatus(Constant.MISSION_STATUS_UNDERWAY);
            myMission.setStatus(mission.getStatus());
            myMission.setUserId(apply.getUserId());
            myMission.setMyDate(new Date());
            /**这里写申请人的id**/
            myMissionMapper.insertSelective(myMission);
            user = userMapper.selectByPrimaryKey(apply.getUserId());
            AppPush.pushSingle("{\"title\":\"猫咪老师\",\"content\":\"喵！~任务已通过,请及时完成哦！\"}", user.getCID());
            AppPush.pushSingle2("{\"title\":\"猫咪老师\",\"content\":\"喵！~任务已通过,请及时完成哦！\",\"payload\":\"喵！~\"}", user.getCID());
            apply.setPublisher(currentUser.getUsername());
            apply.setStartDate(new Date());
            applyMapper.deleteByPrimaryKey(apply.getId());
            i = Constant.APPLY_STATUS_PSSS;
        } else if (Constant.APPLY_STATUS_REFUSE == apply.getStatus()) {
            mission.setTaskStatus(Constant.MISSION_STATUS_REFUSE);
            missionMapper.updateByPrimaryKeySelective(mission);
            user = userMapper.selectByPrimaryKey(apply.getUserId());
            AppPush.pushSingle("{\"title\":\"Test\",\"content\":\"喵！~领取任务失败了哦\"}", user.getCID());
            AppPush.pushSingle2("{\"title\":\"Test\",\"content\":\"喵！~领取任务失败了哦\",\"payload\":\"喵！~\"}", user.getCID());
            apply.setPublisher(currentUser.getUsername());
            apply.setStartDate(new Date());
            pastRecordsMapper.insertApply(apply);
            applyMapper.deleteByPrimaryKey(apply.getId());
            i = Constant.APPLY_STATUS_REFUSE;
        }
        return i;
    }


}
